package SolR;
//TODO reorganze the class remove all the not need thing
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.Map.Entry;

import org.apache.solr.client.solrj.*;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.*;

import Tagger.Tagger;

import Corpus.Corpus;
import Corpus.MetadataType;
import DataObjects.*;
import DisplayDatas.TopicToDisplay;
import Main.*;

public class MySolR extends SolRManager<Article>{

	private HashMap<Integer,Topic> allTopics;
	private Corpus corpus;

	public MySolR(String url,String coreName,HashMap<Integer,Topic> allTopics,Corpus corpus) throws MalformedURLException {
		super(url,coreName);
		this.allTopics=allTopics;
		this.corpus=corpus;
	}

	public MySolR(String url,HashMap<Integer,Topic> allTopics,Corpus corpus) throws MalformedURLException {
		super(url);
		this.allTopics=allTopics;
		this.corpus=corpus;
	}

	protected void addType(SolrInputDocument doc, Article type) {
		doc.addField("id", type.getId());
		doc.addField("name", type.getText());
		doc.addField("title", type.getTitle());

		Collection<Topic> topics = type.getTopics();
		Iterator<Topic> iterator = topics.iterator();
		while(iterator.hasNext()){
			doc.addField("content_type",iterator.next().getId()) ;//TODO is it ok?
		}

		Collection<Pair<String,Object>> metadata=type.getMetadata();

		for(Pair<String,Object> oneMetadata : metadata){
			doc.addField(oneMetadata.getFirst(), oneMetadata.getSecend());
		}
	}

	@SuppressWarnings("unchecked")
	protected Article getType(SolrDocument resultDoc) {
		int id=Integer.parseInt((String)getField("id", resultDoc));

		String text=(String)getField("name", resultDoc);
		String title=(String)getField("title", resultDoc);

		Collection<Threesome<String,String,MetadataType>> allMetadata=corpus.getAllMetadataNames();
		Collection<Pair<String,Object>> metadataAndValues=new LinkedList<Pair<String,Object>>();


		for(Threesome<String,String,MetadataType> oneMetadata : allMetadata){			

			Object metadatavalue=getField(oneMetadata.getFirst(), resultDoc);	
			if (metadatavalue==null){
				metadatavalue="Unknown";
			}

			metadataAndValues.add(new Pair<String, Object>(oneMetadata.getFirst(), metadatavalue));
		}

		System.out.println("MySolR : getType metadataAndValues="+metadataAndValues);//TODO

		Article ans=new Article(id,title,text,metadataAndValues);

		Object t1=(Object)getField("content_type", resultDoc);
		ArrayList<String> topics=null;
		if (t1 instanceof String){
			topics=new ArrayList<String>();
			topics.add((String)t1);
		}
		else
			topics=(ArrayList<String>)getField("content_type", resultDoc);

		for(String topic : topics){
			int topicId=Integer.parseInt(topic);
			Topic realTopic=allTopics.get(topicId);
			ans.addTopic(realTopic);
		}

		return ans;
	}
	
	public HashMap<Integer, TopicToDisplay> smallHash(HashMap<Integer, TopicToDisplay> hash){
		Comparator<TopicToDisplay> cmp=new Comparator<TopicToDisplay>() {
			
			@Override
			public int compare(TopicToDisplay o1, TopicToDisplay o2) {
				int id1=o1.getCountFound();
				int id2=o2.getCountFound();
				return id1-id2;
			}
		};
		
		PriorityQueue<TopicToDisplay> queue=new PriorityQueue<TopicToDisplay>(Consts.NUMBER_OF_TOPICS_TO_SHOW,cmp);
		for(TopicToDisplay topic : hash.values()){
			queue.add(topic);
		}
		
		HashMap<Integer, TopicToDisplay> ans=new HashMap<Integer, TopicToDisplay>();
		for(int i=0;i<Consts.NUMBER_OF_TOPICS_TO_SHOW;i++){
			TopicToDisplay topic=queue.poll();
			if (topic==null)
				break;
			ans.put(topic.getId(), topic);
		}
		return ans;
	}

	@SuppressWarnings("unchecked")
	public HashMap<Integer, TopicToDisplay> queryTopics(String query) throws SolrServerException{
		query=query.replace("\\", "");
		HashMap<Integer, TopicToDisplay> ans=new HashMap<Integer, TopicToDisplay>();
		SolrQuery query1 = new SolrQuery();
		query1.setQuery(query);

		query1.setHighlight(true).setHighlightSnippets(1); //set other params as needed
		query1.setParam("hl.fl", "content");
		query1.setRows(10000000);
		query1.setFields("content_type");
		//query1.addFilterQuery("content_type");

		QueryResponse queryResponse = server.query(query1);
		Iterator<SolrDocument> iter = queryResponse.getResults().iterator();

		while (iter.hasNext()) {
			SolrDocument resultDoc = iter.next();
			ArrayList<String> topics=null;
			Object t1=getField("content_type", resultDoc);
			if (t1 instanceof String){
				topics=new ArrayList<String>();
				topics.add((String)t1);
			}
			else
				topics=(ArrayList<String>)getField("content_type", resultDoc);
			for(String topic : topics){
				int topicId=Integer.parseInt(topic);
				TopicToDisplay index=ans.get(topicId);
				if (index==null){
					index=new TopicToDisplay(allTopics.get(topicId));
					ans.put(topicId, index);
				}
				index.addToCountFound();
			}
		}
//		System.out.println("mySolR - queryTopics :\n"+ans);//TODO
//		System.out.println("mySolR - queryTopics :\n"+smallHash(ans));//TODO
		//return smallHash(ans);
		return ans;
	}

	private Vector<Pair<String, Integer>> minimize(HashMap<String, Integer> cats){
		Vector<Pair<String, Integer>> ans=new Vector<Pair<String,Integer>>();
		for(int i=0;i<Consts.NUMBER_OF_TOPICS_TO_SHOW;i++){
			int max=0;
			String maxName="";
			for(Entry<String, Integer> cat : cats.entrySet()){
				if (cat.getValue()>max){
					max=cat.getValue();
					maxName=cat.getKey();
				}
			}
			cats.remove(maxName);
			ans.add(new Pair<String, Integer>(maxName, max));
		}
		return ans;
	}

	//TODO copied code - to change
	@SuppressWarnings("unchecked")
	public Vector<Pair<String, Integer>> queryCats(String query) throws SolrServerException{
		query=query.replace("\\", "");
		HashMap<String, Integer> ans=new HashMap<String, Integer>();
		SolrQuery query1 = new SolrQuery();
		query1.setQuery(query);

		query1.setHighlight(true).setHighlightSnippets(1); //set other params as needed
		query1.setParam("hl.fl", "content");
		query1.setRows(10000000);
		query1.setFields("cat");
		//query1.addFilterQuery("content_type");

		QueryResponse queryResponse = server.query(query1);

		System.out.println("MySolR.queryCats "+query1);

		Iterator<SolrDocument> iter = queryResponse.getResults().iterator();

		while (iter.hasNext()) {
			SolrDocument resultDoc = iter.next();
			ArrayList<String> cats=null;
			Object t1=getField("cat", resultDoc);
			if (t1 instanceof String){
				cats=new ArrayList<String>();
				cats.add((String)t1);
			}
			else
				cats=(ArrayList<String>)getField("cat", resultDoc);
			if (cats==null){
				cats = new ArrayList<String>();
			}
			for(String cat : cats){
				Integer count=ans.get(cat);
				if (count==null){				
					ans.put(cat, 1);
				}
				else{
					ans.remove(cat);
					ans.put(cat, count+1);
				}
			}
		}
		//		System.out.println("MySolR.queryCats hash="+ans);//TODO
		Vector<Pair<String, Integer>> ans2=minimize(ans);
		return ans2;
	}

	//	private int lineToId(String line){
	////		System.out.println(line);//TODO
	//		String allPath=line.split(" ")[1];
	////		System.out.println(allPath);
	////		System.out.println(allPath.charAt(7)+" "+(int)allPath.charAt(7));
	//		//String[] bySlesh=allPath.split(""+(char)92);
	//		//String[] bySlesh
	//		boolean foundPoint=false;
	//		String id="";
	//		for(int i=allPath.length()-1;i>=0;i--){
	//			if (allPath.charAt(i)=='\\'){
	//				break;
	//			}
	//			if(foundPoint){
	//				id=allPath.charAt(i)+id;
	//			}
	//			if(allPath.charAt(i)=='.'){
	//				foundPoint=true;
	//			}
	//		}
	////		//String fileName=bySlesh[bySlesh.length-1];
	////		String id=fileName.split(".")[0];
	////		System.out.println(id);//TODO
	//		return Integer.parseInt(id);
	//	}

	//	private void addTopics(Article article,String line){
	//		String[] splited = line.split(" ");
	//		String topicId = "";
	//		String topicDist="";
	//		for (int i=2; i<splited.length; i+=2){
	//			topicId=splited[i];
	//			topicDist=splited[i+1];
	//			if (Double.parseDouble(topicDist)>=Consts.MIN_DISTRIBUTION | i/2-1<Consts.MIN_TOPICS_IN_ARTICLE){
	//				article.addTopic(allTopics.get(Integer.parseInt(topicId)));
	//			}
	//		}
	//	}

	//	private void toHashMap(String fileName,BufferedReader bufferReader,Corpus corpus,Tagger tagger) throws SolrServerException, IOException{
	//		Iterator<Pair<Article,String>> iterator=corpus.getIteratorForTheArticles();
	//		
	//		while (iterator.hasNext()){
	//			Pair<Article,String> evar=iterator.next();
	//			Vector<String> vec=String2.split(evar.getSecend(), "\\");
	//			tagger.addArticleTopics(evar.getFirst(), vec.get(vec.size()-1));
	//			addDocument(evar.getFirst());
	//		}
	//		
	//		
	////		XMLReaderWiki xmlReader=new XMLReaderWiki();//TODO
	////		LinkedList<Article> articles=xmlReader.read(fileName);
	////		
	////		String line=bufferReader.readLine();
	////		int id=lineToId(line);
	////		for(Article article : articles){
	////			if (id!=article.getId())
	////				continue;
	////			addTopics(article,line);
	////			addDocument(article);
	////			
	////			line=bufferReader.readLine();
	////			if (line==null)
	////				break;
	////			id=lineToId(line);
	////		}
	//	}

	public void init(Corpus corpus,Tagger tagger) throws SolrServerException, IOException{
		deleteAll();//TODO 

		Iterator<Pair<Article,String>> iterator=corpus.getIteratorForTheArticles();

		System.out.println("MaSolR:start init - after delete");//TODO
		int i=0;
		int j=0;
		Vector<Article> articles=new Vector<Article>();

		while (iterator.hasNext()){
			Pair<Article,String> evar=iterator.next();
			Vector<String> vec=String2.split(evar.getSecend(), "\\");
			tagger.addArticleTopics(evar.getFirst(), vec.get(vec.size()-1));

			//			addDocument(evar.getFirst());
			if (!evar.getFirst().getText().trim().equals("")){
				articles.add(evar.getFirst());
				if (i==1000){
					addDocument(articles);
					articles=new Vector<Article>();
					i=0;
					System.out.println("aaa "+j);//TODO
					j++;
				}
				else{
					i++;
				}
			}

		}//end while
		System.out.println("MySolR.init start to last upload "+articles.size());//TODO
		addDocument(articles);
		System.out.println("MySolR.init end to last upload");//TODO		
	}
}
